﻿using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using NLog;

namespace ConsoleService
{
    public static class ConsoleAPI
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();

        private static string _serviceURL;
        private static string _userName;
        private static string _password;
        private static User _user;
        private static List<RestResponseCookie> _session_cookies;

        private static bool _isAuthenticated;
        public static bool IsAuthenticated { get { return _isAuthenticated; } }

        public static RestSharp.IRestClient Client { get; internal set; }

        static ConsoleAPI()
        {
            _serviceURL = System.Configuration.ConfigurationManager.AppSettings.Get("ConsoleAPI");
            _userName = System.Configuration.ConfigurationManager.AppSettings.Get("APIUser");
            _password = System.Configuration.ConfigurationManager.AppSettings.Get("APIPwd");
            Client = new RestClient(_serviceURL);
            _isAuthenticated = false;
            GetSession();
        }

        private static void CheckResponse(IRestResponse response)
        {
            if (response.StatusCode == HttpStatusCode.Forbidden
                || response.StatusCode == HttpStatusCode.Unauthorized
                || response.StatusCode == HttpStatusCode.MethodNotAllowed)
            {
                ConsoleAPI._isAuthenticated = false;
                GetSession();
            }
        }

        private static void SetCookies(IRestRequest request)
        {
            if (request != null && ConsoleAPI._session_cookies != null)
            {
                foreach (var cookie in ConsoleAPI._session_cookies)
                {
                    request.AddCookie(cookie.Name, cookie.Value);
                }
            }
        }

        public static void GetSession()
        {
            try
            {
                var request = new RestRequest("users/sessions", Method.GET);
                request.AddParameter("login", ConsoleAPI._userName); // adds to POST or URL querystring based on Method
                request.AddParameter("password", ConsoleAPI._password); // adds to POST or URL querystring based on Method

                //request.AddUrlSegment("id", 123);
                // easily add HTTP Headers
                //request.AddHeader("header", "value");

                //RestResponse response = client.Execute(request);
                //var content = response.Content; // raw content as string

                // or automatically deserialize result
                // return content type is sniffed but can be explicitly set via RestClient.AddHandler();
                IRestResponse<List<User>> response = Client.Execute<List<User>>(request);
                if (response.Data != null && response.Data.Count > 0)
                {
                    if (response.Cookies.Count > 0)
                    {
                        _session_cookies = response.Cookies.ToList();
                    }
                    _user = response.Data[0];
                }
                else
                {
                    _session_cookies = new List<RestResponseCookie>();
                }
                if (_user != null && _user.user_id > 0)
                {
                    logger.Trace(string.Format("User is authenticated: {0}", _user.user_id));
                    _isAuthenticated = true;
                }
            }
            catch (Exception ex)
            {
                logger.Error("GetSession", ex);
            }
        }

        public static IEnumerable<Server> GetServers()
        {
            var request = new RestRequest("servers/templates", Method.GET);
            SetCookies(request);
            IRestResponse<List<Server>> response = Client.Execute<List<Server>>(request);
            logger.Trace("GetServers Response: {0}", response.Content);
            ConsoleAPI.CheckResponse(response);
            return response.Data;
        }

        public static Server SaveServer(Server server)
        {
            var request = new RestRequest("servers/", Method.POST);
            SetCookies(request);
            request.AddObject(server,server.getJSON());
            IRestResponse<Server> response = Client.Execute<Server>(request);
            logger.Trace("SaveServer {0} Response: {1}", server.server_id, response.Content);
            ConsoleAPI.CheckResponse(response);
            return response.Data;
        }

        public static IEnumerable<Action> GetActions()
        {
            var request = new RestRequest("actions/", Method.GET);
            SetCookies(request);
            request.AddParameter("active", "1");
            IRestResponse<List<Action>> response = Client.Execute<List<Action>>(request);
            logger.Trace("GetActions Response: {0}", response.Content);
            ConsoleAPI.CheckResponse(response);
            return response.Data;
        }

        public static Action SaveAction(Action action)
        {
            var request = new RestRequest("actions/", Method.POST);
            SetCookies(request);
            request.AddObject(action);
            IRestResponse<Action> response = Client.Execute<Action>(request);
            logger.Trace("SaveAction {0} Response: {1}", action.action_id, response.Content);
            ConsoleAPI.CheckResponse(response);
            return response.Data;
        }

        public static Player PostPlayer(Player player)
        {
            var request = new RestRequest("players/", Method.POST);
            SetCookies(request);
            request.AddObject(player);
            IRestResponse<Player> response = Client.Execute<Player>(request);
            logger.Trace("PostPlayer {0} Response: {1}", player.guid, response.Content);
            ConsoleAPI.CheckResponse(response);
            return response.Data;
        }
    }
}
